package pc

import (
	. "chess_platform/internal/common"
	"chess_platform/models/partner"
	"chess_platform/models/pc"
	"chess_platform/modules"
	"fmt"
	"time"
)

//[pc]partner:合伙人系统管理
type PartnerController struct {
	GrantController
}

func (b *PartnerController) URLMapping() {
	//finance:财务方面
	b.Mapping("ListPartnerOrder", b.ListPartnerOrder)
	b.Mapping("DeliveryPartnerCard", b.DeliveryPartnerCard)

	//user:合伙人用户管理
	b.Mapping("NewUser", b.NewUser)
	b.Mapping("UpdateUser", b.UpdateUser)
	b.Mapping("UserInfo", b.UserInfo)
	b.Mapping("ListUser", b.ListUser)

	//formal:代理列表
	b.Mapping("ListPartnerUser", b.ListPartnerUser)
	b.Mapping("ChangeAgentRelation", b.ChangeAgentRelation)

	//bonus:公司提成
	b.Mapping("ListCashRecord", b.ListCashRecord)

	//withdraw:提现列表
	b.Mapping("ListWithdraw", b.ListWithdraw)
	b.Mapping("UpdateWithdraw", b.UpdateWithdraw)

}

//------------------------------合伙人系统代理的订单-----------------------------------------------------

// @Title 代理的订单列表(支付记录)
// @Description 代理的订单列表(支付记录)
// @Param   start_time         body   int     false      "下单开始时间"
// @Param   end_time           body   int     false      "下单结束时间"
// @Param   page_size          body   int     true       "每页显示数量"
// @Param   page_index         body   int     true       "第几页"
// @Param   uid          	   body   int     false      "用户id"
// @Param   transaction_id     body   string  false      "微信订单号"
// @Param   id                 body   int     false      "平台订单号"
// @Param   status             body   int     false      "订单状态,0-所有状态,1-未支付,2-已关闭,3-支付错误,4-支付成功,未发货,5-已发货'"
// @Success 0 {object} []common.Order 订单(支付)列表
// @router /finance/list-partner-order [post]
func (b *PartnerController) ListPartnerOrder() {
	type Params struct {
		ListParams
		ListDayParams
		AllOrderParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	cr, amount, count, err := pc.ListPartnerOrder(p.ListParams, p.ListDayParams, p.AllOrderParams)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = map[string]interface{}{
		"order":  cr,
		"amount": amount,
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 补发货(钻石)
// @Description 补发货(钻石)
// @Param   id              body   int        true        "id"
// @Success 0 {string}  状态码
// @router /finance/delivery-card [post]
func (b *PartnerController) DeliveryPartnerCard() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	order, err := partner.OrderById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if order == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrOrderNotFound
		b.Response()
		return
	}
	if order.Status == OrderDelivered {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = MsgAlreadyDeliveryCard
		b.Response()
		return
	}
	if order.Status != OrderPaySuccess {
		b.Res.Code = ErrOrderNotPaySuccess
		b.Res.Msg = MsgOrderNotPaySuccess
		b.Response()
		return
	}
	err = modules.DealPfAgentPay(order)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	msg := fmt.Sprintf("发货给合伙人系统代理(uid:%v)成功,平台订单号:%v", order.Uid, order.Id)
	b.NewLog(LogFinance, OpUpdate, msg, map[string]interface{}{})
	b.ResponseSuccess()
}

//--------------------------下面是合伙人帐号管理--------------------------

// @Title 创建合伙人用户
// @Description 创建合伙人用户
// @Param   name     	body    string  true      "用户名"
// @Param   phone     	body    string  true      "手机号"
// @Param   real_name   body    string  true      "真实名字"
// @Param   password 	body    string  true      "密码"
// @Param   wechat_agent     body    string  true      "微信号(招聘代理)"
// @Param   wechat_business  body    string  true      "微信号(商务合作)"
// @Param   bonus_rate	body    int     true      "公司的提成比例,存时乘以100,展示时除以100"
// @Success 0 {string} 状态码
// @Failure 399
// @router /user/new-user [post]
func (b *PartnerController) NewUser() {
	var p PbUser
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Name, "name").Message("用户名不能为空")
	b.Valid.MinSize(p.Name, 3, "name").Message("用户名长度为3-12个字符")
	b.Valid.MaxSize(p.Name, 12, "name").Message("用户名长度为3-12个字符")
	b.Valid.AlphaDash(p.Name, "name").Message("用户名只支持字符为0-9a-zA-Z_-")

	b.Valid.Required(p.RealName, "real_name").Message("真实名字不能为空")
	b.Valid.MinSize(p.RealName, 2, "real_name").Message("真实名字长度为2-12个字符")
	b.Valid.MaxSize(p.RealName, 12, "real_name").Message("真实名字长度为2-12个字符")

	b.Valid.Required(p.Password, "password").Message("密码不能为空")
	b.Valid.MinSize(p.Password, 6, "password").Message("密码长度为6-15个字符")
	b.Valid.MaxSize(p.Password, 15, "password").Message("密码长度为6-15个字符")
	b.Valid.Required(p.Password, "password").Message("密码不能为空")

	b.Valid.Range(p.BonusRate, 0, 10000, "bonus_rate").Message("提成比例取值范围0%-100%")
	if !b.VerifyParamsError() {
		return
	}

	_, ok := pc.IsPbUserExist(p.Name)
	if ok {
		b.Res.Code = ErrUserAlreadyExist
		b.Res.Msg = MsgErrUserAlreadyExist
		b.Response()
		return
	}

	p.Password = Md5sum(p.Password)
	user := map[string]interface{}{
		"name":            p.Name,
		"phone":           p.Phone,
		"real_name":       p.RealName,
		"password":        p.Password,
		"bonus_rate":      p.BonusRate,
		"wechat_agent":    p.WechatAgent,
		"wechat_business": p.WechatBusiness,
		"create_time":     time.Now().Unix(),
	}
	_, err := pc.NewPbUser(user)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 更新合伙人用户
// @Description 更新合伙人用户
// @Param   uid       	body    int     true      "用户id"
// @Param   name     	body    string  true      "用户名"
// @Param   phone     	body    string  true      "手机号"
// @Param   real_name   body    string  true      "真实名字"
// @Param   password 	body    string  true      "密码"
// @Param   wechat_agent     body    string  true      "微信号(招聘代理)"
// @Param   wechat_business  body    string  true      "微信号(商务合作)"
// @Param   bonus_rate	body    int     true      "公司的提成比例,存时乘以100,展示时除以100"
// @Success 0 {string} 状态码
// @Failure 399
// @router /user/update-user [post]
func (b *PartnerController) UpdateUser() {
	var p PbUser
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Uid, "uid").Message("用户Id不能为零")
	b.Valid.Required(p.Name, "name").Message("用户名不能为空")
	b.Valid.MinSize(p.Name, 3, "name").Message("用户名长度为3-12个字符")
	b.Valid.MaxSize(p.Name, 12, "name").Message("用户名长度为3-12个字符")
	b.Valid.AlphaDash(p.Name, "name").Message("用户名只支持字符为0-9a-zA-Z_-")

	b.Valid.Required(p.RealName, "real_name").Message("真实名字不能为空")
	b.Valid.MinSize(p.RealName, 2, "real_name").Message("真实名字长度为2-12个字符")
	b.Valid.MaxSize(p.RealName, 12, "real_name").Message("真实名字长度为2-12个字符")

	if p.Password != "" {
		b.Valid.MinSize(p.Password, 6, "password").Message("密码长度为6-15个字符")
		b.Valid.MaxSize(p.Password, 15, "password").Message("密码长度为6-15个字符")
	}

	b.Valid.Range(p.BonusRate, 0, 10000, "bonus_rate").Message("提成比例取值范围0%-100%")
	if !b.VerifyParamsError() {
		return
	}

	user := map[string]interface{}{
		"name":            p.Name,
		"phone":           p.Phone,
		"real_name":       p.RealName,
		"bonus_rate":      p.BonusRate,
		"wechat_agent":    p.WechatAgent,
		"wechat_business": p.WechatBusiness,
	}
	if p.Password != "" {
		user["password"] = Md5sum(p.Password)
	}
	_, err := pc.UpdatePbUser(user, p.Uid)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
}

// @Title 合伙人用户详情
// @Description 合伙人用户详情
// @Param   uid  body    int     true      "用户uid"
// @Success 0 {object} common.PbUser 用户信息
// @router /user/user-info [post]
func (b *PartnerController) UserInfo() {
	type Params struct {
		Uid int64 `json:"uid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	user, err := pc.PbUserInfoById(p.Uid)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = user
	b.ResponseSuccess()
}

// @Title 获取合伙人用户列表
// @Description 获取合伙人用户列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   name         body   string  false      "搜索用户名字"
// @Success 0 {object} []common.PbUser 用户列表
// @router /user/list-user [post]
func (b *PartnerController) ListUser() {
	type Params struct {
		ListParams
		Name string `json:"name"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	users, count, err := pc.ListPbUserInfo(p.ListParams, p.Name)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = users
	b.Res.Count = count
	b.ResponseSuccess()
}

//-------------------------------------以下是合伙人系统代理列表方面的-------------------------------

// @Title 获取所有合伙人代理(包括总代)
// @Description 获取所有合伙人代理(包括总代)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   group_id     body   int     false      "合伙人的id,0-表示所有合伙人"
// @Param   pid          body   int     false      "查询此代理下的下级代理"
// @Param   root_id      body   int     false      "查询此总代下的所有下级代理"
// @Param   level        body   int     false      "0-所有代理,1-总代(一级代理),2-二级代理,3-三级代理,以此类推"
// @Param   agent_id     body   int     false      "某个具体的代理id"
// @Param   agent_name 	 body   string  false      "代理的名字"
// @Param   order_name 	 body   string  false      "排序名字,total_card_num,card_num,open_fee"
// @Param   order        body   int     false      "1-升序,2-降序"
// @Success 0 {object} []common.H5User 代理用户列表
// @router /formal/list-partner-user [post]
func (b *PartnerController) ListPartnerUser() {
	type Params struct {
		ListParams
		PfAgentParams
		OrderParams
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	users, count, err := pc.ListPartnerUser(p.ListParams, p.OrderParams, p.PfAgentParams)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	oc := NewDBOrm(DBChess)
	o := NewDBOrm(DBChessPartner)
	for _, v := range users {
		v["player_count"] = partner.CountAgentPlayer(v["uid"], oc)
		v["agent_count"] = partner.CountNextLevelAgent(v["uid"], o)
		v["root_count"] = partner.CountRootAgent(v["root_id"], o)
	}

	b.Res.Data = users
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 合伙人系统,改变总代或普通代理所属的合伙人或上级
// @Description 合伙人系统,改变总代或普通代理所属的合伙人或上级
// @Param   type           body   int     true       "要改变的代理的所属上级还是所属的合伙人(1-上级代理,2-合伙人)"
// @Param   uid            body   int     true       "要改变的代理的id"
// @Param   pid            body   int     true       "新的所属代理的上级id或合伙人ID"
// @Success 0 {string} 状态码
// @router /formal/change-agent-relation [post]
func (b *PartnerController) ChangeAgentRelation() {
	type Params struct {
		Type int64 `json:"type" valid:"Range(1,2)"`
		Uid  int64 `json:"uid" valid:"Required"`
		Pid  int64 `json:"pid" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	/*
			1. 如果普通代理要修改合伙人,那么此代理成为新合伙人名下的总代,同时需要修改此代理名下的所有代理的等级向上提，
			   但这要从树的根部遍历到各片叶子，不现实，所以限定此代理名下不能有代理的才能修改合伙人
		    2. 如果是总代要修改合伙人，直接修改，同时修改名下所有代理的合伙人的id，可以很容易实现，因为每个代理都记录了总代的id

		    3. 如果修改普通代理的所属代理，如果此代理已有下级代理则不能修改，因为要修改所有下级的level很难改
			4. 修改归属
	*/

	if p.Type == 1 { //要改变代理的上级代理归属
		//判断是否有下级代理
		if pc.CountNextLevelAgent(p.Uid) > 0 {
			b.ResponseFail("此代理名下有代理,不能修改所属上级代理")
			return
		}
		//获取新的上一级代理的信息
		field := []string{"root_id", "group_id", "level"}
		up, err := partner.SpecifyUserInfoById(p.Pid, field)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		if up == nil {
			b.ResponseFail("新的上级代理不存在,请检查输入")
			return
		}
		data := map[string]interface{}{
			"root_id":  up.RootId,
			"group_id": up.GroupId,
			"level":    up.Level + 1,
			"pid":      p.Pid,
		}
		_, err = partner.UpdateUser(data, p.Uid)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		b.ResponseSuccess()
		return
	} else if p.Type == 2 { //
		//获取代理的信息
		field := []string{"level"}
		self, err := partner.SpecifyUserInfoById(p.Uid, field)
		if err != nil {
			LogPF.Error(b.DatabaseError(err.Error()))
			return
		}
		if self == nil {
			b.ResponseFail("代理不存在,请检查输入")
			return
		}
		if self.Level == Level1 { //总代,直接修改名下所有代理的group_id
			data := map[string]interface{}{
				"group_id": p.Pid,
			}
			_, err = partner.UpdateUserByRootId(data, p.Uid)
			if err != nil {
				LogPF.Error(b.DatabaseError(err.Error()))
				return
			}
			b.ResponseSuccess()

		} else {
			//判断是否有下级代理
			if pc.CountNextLevelAgent(p.Uid) > 0 {
				b.ResponseFail("此代理名下有代理,不能修改所属上级代理")
				return
			}
			//成为新合伙人的总代
			data := map[string]interface{}{
				"group_id": p.Pid,
				"level":    Level1,
				"root_id":  p.Uid,
				"pid":      0,
			}
			_, err = partner.UpdateUser(data, p.Uid)
			if err != nil {
				LogPF.Error(b.DatabaseError(err.Error()))
				return
			}
			b.ResponseSuccess()

		}
	}
}

// @Title 合伙人系统公司的提成收入
// @Description 合伙人系统公司的提成收入
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.CashRecord
// @router /bonus/list-cash-record [post]
func (b *PartnerController) ListCashRecord() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	cr, count, err := pc.ListCashRecord(p)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = cr
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 合伙人系统代理的提现列表
// @Description 合伙人系统代理的提现列表
// @Param   start_time   body   int     true       "开始时间"
// @Param   end_time     body   int     true       "结束时间"
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   id           body   int     false      "提现单号"
// @Param   uid          body   int     false      "代理id"
// @Param   status       body   int     false      "提现状态,1-审批中,2-审批成功,3-审批失败,4-支付中,5-支付失败,6-支付成功"
// @Success 0 {object} []common.WithdrawRecord
// @router /withdraw/list-withdraw [post]
func (b *PartnerController) ListWithdraw() {
	type Params struct {
		ListParams
		ListDayParams
		Id     int64 `json:"id"`
		Uid    int64 `json:"uid"`
		Status int64 `json:"status"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	cr, count, pAmount, uAmount, err := pc.ListPfWithdraw(p.ListParams, p.ListDayParams, p.Id, p.Uid, p.Status)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = map[string]interface{}{
		"unprocessed_amount": uAmount,
		"processed_amount":   pAmount,
		"withdraw_list":      cr,
	}
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 更新提现记录状态
// @Description 更新提现记录状态
// @Param   id           body   int     true       "id"
// @Param   status       body   int     true       "状态"
// @Param   fail_reason  body   int     false      "失败原因,最多32字符"
// @Success 0 {string}  状态码
// @router /withdraw/update-withdraw [post]
func (b *PartnerController) UpdateWithdraw() {
	type Params struct {
		Id         int64  `json:"id" valid:"Required"`
		Status     int64  `json:"status" valid:"Range(2,6)"`
		FailReason string `json:"fail_reason"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if p.FailReason != "" {
		b.Valid.MaxSize(p.FailReason, 32, "fail_reason").Message("最多32个字符")
	}
	if !b.ValidParams(&p) {
		return
	}
	wr, err := pc.PfWithdrawById(p.Id)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	if wr == nil {
		b.Res.Code = ErrNotFound
		b.Res.Msg = MsgErrWithdrawNotFound
		b.Response()
		return
	}
	if wr.Status == WithdrawPaySuccess {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = "提现已经支付成功,不能再改变其状态"
		b.Response()
		return
	}
	if wr.Status == WithdrawApproveFail || wr.Status == WithdrawPayFail {
		b.Res.Code = ErrOperationRepeat
		b.Res.Msg = "提现为失败状态,不能再改变其状态"
		b.Response()
		return
	}

	//状态改为失败时，要把钱退还给代理
	if p.Status == WithdrawPayFail || wr.Status == WithdrawApproveFail {
		o := NewDBOrm(DBChessPartner)
		o.Begin()
		defer o.Rollback()
		//提现金额退回记录
		cr := map[string]interface{}{
			"agent_id":    b.Uid,
			"type":        CashWithdrawReturn,
			"amount":      wr.Amount,
			"month":       CurrentYearMonth(),
			"create_time": time.Now().Unix(),
		}
		_, err = partner.NewCashRecord(cr, o)
		if err != nil {
			o.Rollback()
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		//提现金额退回
		n, err := partner.UpdateCash(wr.Amount, b.Uid, false, o)
		if err != nil || n == 0 {
			o.Rollback()
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}

		data := map[string]interface{}{
			"status":      p.Status,
			"fail_reason": p.FailReason,
		}
		_, err = pc.UpdatePfWithdraw(data, p.Id, o)
		if err != nil {
			o.Rollback()
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		o.Commit()
		b.ResponseSuccess()
		msg := fmt.Sprintf("更新提现单状态(状态ID:%v,提现单号:%v)", p.Status, p.Id)
		b.NewLog(LogFinance, OpUpdate, msg, data)
	} else {
		data := map[string]interface{}{
			"status":      p.Status,
			"fail_reason": p.FailReason,
		}
		if p.Status == WithdrawPaySuccess {
			data["pay_time"] = time.Now().Unix()
		}
		_, err = pc.UpdatePfWithdraw(data, p.Id)
		if err != nil {
			LogPc.Error(b.DatabaseError(err.Error()))
			return
		}
		b.ResponseSuccess()
		msg := fmt.Sprintf("更新提现单状态(状态ID:%v,提现单号:%v)", p.Status, p.Id)
		b.NewLog(LogFinance, OpUpdate, msg, data)
	}
}
